<html lang="zh-CN"><head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>高级人机验证系统</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
    
    <!-- 配置Tailwind自定义颜色和字体 -->
    <script>
        tailwind.config = {
            theme: {
                extend: {
                    colors: {
                        primary: '#3B82F6',
                        secondary: '#10B981',
                        danger: '#EF4444',
                        neutral: '#6B7280',
                        light: '#F3F4F6',
                    },
                    fontFamily: {
                        sans: ['Inter', 'system-ui', 'sans-serif'],
                    },
                }
            }
        }
    </script>
    
    <style type="text/tailwindcss">
        @layer utilities {
            .content-auto {
                content-visibility: auto;
            }
            .captcha-bg {
                background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M11 18c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm48 25c3.866 0 7-3.134 7-7s-3.134-7-7-7-7 3.134-7 7 3.134 7 7 7zm-43-7c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm63 31c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM34 90c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zm56-76c1.657 0 3-1.343 3-3s-1.343-3-3-3-3 1.343-3 3 1.343 3 3 3zM12 86c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm28-65c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm23-11c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-6 60c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm29 22c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zM32 63c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm57-13c2.76 0 5-2.24 5-5s-2.24-5-5-5-5 2.24-5 5 2.24 5 5 5zm-9-21c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM60 91c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM35 41c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2zM12 60c1.105 0 2-.895 2-2s-.895-2-2-2-2 .895-2 2 .895 2 2 2z' fill='%239C92AC' fill-opacity='0.1' fill-rule='evenodd'/%3E%3C/svg%3E");
            }
            .noise {
                position: relative;
            }
            .noise::after {
                content: "";
                position: absolute;
                top: 0;
                left: 0;
                width: 100%;
                height: 100%;
                background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)' opacity='0.1'/%3E%3C/svg%3E");
                pointer-events: none;
            }
            .test-result {
                transition: all 0.3s ease;
            }
            .slider-container {
                position: relative;
                width: 100%;
                height: 180px;
                overflow: hidden;
                border-radius: 8px;
                background-color: #f5f5f5;
                margin-bottom: 16px;
            }
            .puzzle-image {
                width: 100%;
                height: 100%;
                background-size: cover;
                background-position: center;
                position: relative;
            }
            .puzzle-missing {
                position: absolute;
                width: 60px;
                height: 60px;
                background-color: rgba(255, 255, 255, 0.1);
                border: 2px dashed #ccc;
                box-sizing: border-box;
            }
            .puzzle-piece {
                position: absolute;
                width: 60px;
                height: 60px;
                background-size: 300px 180px; /* 与原图尺寸匹配 */
                background-position: 0 0;
                border: 2px solid white;
                box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
                cursor: grab;
                transition: box-shadow 0.2s;
                z-index: 2;
            }
            .puzzle-piece:active {
                cursor: grabbing;
                box-shadow: 0 0 15px rgba(0, 0, 0, 0.5);
            }
            .slider-track {
                width: 100%;
                height: 50px;
                background-color: #f1f1f1;
                border-radius: 25px;
                position: relative;
                margin-bottom: 8px;
            }
            .slider-button {
                position: absolute;
                width: 50px;
                height: 50px;
                background-color: white;
                border: 2px solid #e0e0e0;
                border-radius: 50%;
                box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
                display: flex;
                align-items: center;
                justify-content: center;
                cursor: grab;
                transition: all 0.1s;
                z-index: 2;
            }
            .slider-button:active {
                cursor: grabbing;
            }
            .slider-progress {
                position: absolute;
                height: 100%;
                background-color: rgba(59, 130, 246, 0.2);
                border-radius: 25px;
                z-index: 1;
                width: 0;
                transition: width 0.1s;
            }
            .slider-text {
                position: absolute;
                width: 100%;
                height: 100%;
                display: flex;
                align-items: center;
                justify-content: center;
                color: #666;
                font-size: 14px;
                z-index: 0;
                user-select: none;
            }
            .recognition-indicator {
                position: absolute;
                bottom: 4px;
                left: 4px;
                font-size: 12px;
                color: rgba(59, 130, 246, 0.7);
                background: rgba(255, 255, 255, 0.8);
                padding: 2px 6px;
                border-radius: 4px;
                z-index: 10;
            }
            #captchaCanvas {
                width: 100%;
                height: 100%;
            }
        }
    </style>
</head>
<body class="bg-gray-50 font-sans min-h-screen">
    <div class="container mx-auto px-4 py-8 max-w-5xl">
        <header class="text-center mb-12">
            <h1 class="text-[clamp(1.8rem,4vw,2.5rem)] font-bold text-gray-800 mb-2">高级人机验证系统</h1>
            <p class="text-gray-600 max-w-2xl mx-auto">带智能测试工具的验证系统，支持字符识别和智能滑块测试</p>
        </header>

        <div class="grid md:grid-cols-2 gap-8">
            <!-- 人机验证区域 -->
            <div class="bg-white rounded-xl shadow-lg p-6 transform transition-all duration-300 hover:shadow-xl">
                <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
                    <i class="fa fa-shield text-primary mr-2"></i>
                    人机验证
                </h2>
                
                <div class="mb-4">
                    <label class="block text-sm font-medium text-gray-700 mb-2">验证类型</label>
                    <div class="flex flex-wrap gap-3">
                        <label class="inline-flex items-center">
                            <input type="radio" name="captchaType" value="text" checked="" class="form-radio text-primary focus:ring-primary">
                            <span class="ml-2 text-gray-700">字符验证</span>
                        </label>
                        <label class="inline-flex items-center">
                            <input type="radio" name="captchaType" value="math" class="form-radio text-primary focus:ring-primary">
                            <span class="ml-2 text-gray-700">数学问题</span>
                        </label>
                        <label class="inline-flex items-center">
                            <input type="radio" name="captchaType" value="slider" class="form-radio text-primary focus:ring-primary">
                            <span class="ml-2 text-gray-700">滑块验证</span>
                        </label>
                    </div>
                </div>
                
                <!-- 验证码显示区域 - 字符和数学验证共用 -->
                <div id="textCaptchaContainer" class="relative captcha-bg noise bg-white border border-gray-300 rounded-lg p-4 mb-4 h-24 flex items-center justify-center">
                    <!-- 替换文本为Canvas元素用于绘制验证码图片 -->
                    <canvas id="captchaCanvas" width="300" height="80"></canvas>
                    <button id="refreshCaptcha" class="absolute right-2 top-2 text-gray-500 hover:text-primary transition-colors">
                        <i class="fa fa-refresh"></i>
                    </button>
                    <div id="textRecognitionIndicator" class="recognition-indicator hidden">
                        <i class="fa fa-eye mr-1"></i>识别中...
                    </div>
                </div>
                
                <!-- 滑块验证区域 -->
                <div id="sliderCaptchaContainer" class="hidden">
                    <div class="slider-container noise relative">
                        <div id="puzzleImage" class="puzzle-image">
                            <div id="puzzleMissing" class="puzzle-missing"></div>
                            <div id="puzzlePiece" class="puzzle-piece"></div>
                        </div>
                        <div id="sliderRecognitionIndicator" class="recognition-indicator hidden">
                            <i class="fa fa-eye mr-1"></i>分析中...
                        </div>
                    </div>
                    
                    <div class="slider-track">
                        <div id="sliderProgress" class="slider-progress"></div>
                        <div id="sliderButton" class="slider-button">
                            <i class="fa fa-angle-right text-primary text-xl"></i>
                        </div>
                        <div id="sliderText" class="slider-text">
                            向右拖动滑块完成拼图
                        </div>
                    </div>
                    
                    <button id="refreshSlider" class="w-full mt-2 py-2 text-sm text-gray-500 hover:text-primary transition-colors flex items-center justify-center">
                        <i class="fa fa-refresh mr-1"></i> 刷新滑块
                    </button>
                </div>
                
                <!-- 输入区域 - 字符和数学验证用 -->
                <div id="textInputContainer" class="mb-4">
                    <label for="userInput" class="block text-sm font-medium text-gray-700 mb-1">请输入上方的内容</label>
                    <div class="flex">
                        <input type="text" id="userInput" class="flex-1 px-4 py-2 border border-gray-300 rounded-l-lg focus:ring-2 focus:ring-primary focus:border-primary transition-all" placeholder="输入验证码">
                        <button id="verifyBtn" class="bg-primary hover:bg-primary/90 text-white px-4 py-2 rounded-r-lg transition-colors">验证</button>
                    </div>
                </div>
                
                <!-- 验证结果 -->
                <div id="verificationResult" class="hidden p-3 rounded-lg mb-4 border"></div>
                
                <div class="text-sm text-gray-500">
                    <p>看不清？点击刷新按钮获取新的验证码</p>
                </div>
            </div>
            
            <!-- 测试程序区域 -->
            <div class="bg-white rounded-xl shadow-lg p-6 transform transition-all duration-300 hover:shadow-xl">
                <h2 class="text-xl font-semibold text-gray-800 mb-4 flex items-center">
                    <i class="fa fa-flask text-secondary mr-2"></i>
                    智能测试工具
                </h2>
                
                <div class="mb-4">
                    <label class="block text-sm font-medium text-gray-700 mb-2">识别精度</label>
                    <div class="flex space-x-4 flex-wrap">
                        <label class="inline-flex items-center">
                            <input type="radio" name="recognitionAccuracy" value="high" checked="" class="form-radio text-secondary focus:ring-secondary">
                            <span class="ml-2 text-gray-700">高精度 (90%)</span>
                        </label>
                        <label class="inline-flex items-center">
                            <input type="radio" name="recognitionAccuracy" value="medium" class="form-radio text-secondary focus:ring-secondary">
                            <span class="ml-2 text-gray-700">中等精度 (70%)</span>
                        </label>
                        <label class="inline-flex items-center">
                            <input type="radio" name="recognitionAccuracy" value="low" class="form-radio text-secondary focus:ring-secondary">
                            <span class="ml-2 text-gray-700">低精度 (50%)</span>
                        </label>
                    </div>
                </div>
                
                <div class="mb-4">
                    <label for="testCount" class="block text-sm font-medium text-gray-700 mb-1">测试次数</label>
                    <input type="number" id="testCount" min="1" max="100" value="5" class="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-secondary focus:border-secondary transition-all">
                </div>
                
                <div class="mb-6">
                    <button id="startTestBtn" class="w-full bg-secondary hover:bg-secondary/90 text-white px-4 py-2 rounded-lg transition-colors flex items-center justify-center">
                        <i class="fa fa-play mr-2"></i>
                        开始智能测试
                    </button>
                </div>
                
                <!-- 测试结果 -->
                <div class="mb-4">
                    <h3 class="text-sm font-medium text-gray-700 mb-2">测试结果</h3>
                    <div id="testResults" class="h-40 overflow-y-auto p-3 border border-gray-200 rounded-lg bg-gray-50 text-sm">
                        准备就绪，点击"开始智能测试"按钮开始...
                    </div>
                </div>
                
                <!-- 测试统计 -->
                <div id="testStats" class="hidden grid grid-cols-3 gap-2 text-center text-sm">
                    <div class="p-2 bg-gray-50 rounded-lg">
                        <div class="text-gray-500">总测试</div>
                        <div id="totalTests" class="font-semibold">0</div>
                    </div>
                    <div class="p-2 bg-gray-50 rounded-lg">
                        <div class="text-gray-500">识别成功</div>
                        <div id="successfulTests" class="font-semibold text-secondary">0</div>
                    </div>
                    <div class="p-2 bg-gray-50 rounded-lg">
                        <div class="text-gray-500">识别失败</div>
                        <div id="failedTests" class="font-semibold text-danger">0</div>
                    </div>
                </div>
            </div>
        </div>
        
        <div class="mt-12 bg-white rounded-xl shadow-lg p-6">
            <h2 class="text-xl font-semibold text-gray-800 mb-4">智能测试工具说明</h2>
            <p class="text-gray-600 mb-4">
                本系统的智能测试工具模拟了自动化识别技术，能够:
            </p>
            <ul class="list-disc list-inside text-gray-600 mb-4 pl-4">
                <li><strong>字符识别</strong>：模拟OCR技术识别字符验证码，识别成功率可调节</li>
                <li><strong>滑块分析</strong>：模拟图像分析技术确定滑块目标位置，模拟人类拖动行为</li>
                <li><strong>智能决策</strong>：根据设定的识别精度，模拟不同水平的识别系统</li>
            </ul>
            <p class="text-gray-600">
                测试工具会显示识别过程和结果，帮助评估验证系统对自动化攻击的防御能力。高精度模式模拟先进的识别技术，低精度模式模拟初级识别工具。
            </p>
        </div>
        
        <footer class="mt-12 text-center text-gray-500 text-sm">
            <p>明七工作室 © 2025</p>
        </footer>
    </div>

    <script>
        // 字符识别模拟器
        class CharacterRecognizer {
            constructor() {
                // 字符特征库 - 模拟字符的特征数据
                this.characterFeatures = {
                    'A': { strokes: 3, symmetry: 'vertical', complexity: 2 },
                    'B': { strokes: 2, symmetry: 'horizontal', complexity: 3 },
                    'C': { strokes: 1, symmetry: 'horizontal', complexity: 1 },
                    'D': { strokes: 2, symmetry: 'vertical', complexity: 2 },
                    'E': { strokes: 4, symmetry: 'none', complexity: 2 },
                    'F': { strokes: 3, symmetry: 'none', complexity: 2 },
                    'G': { strokes: 1, symmetry: 'none', complexity: 2 },
                    'H': { strokes: 3, symmetry: 'vertical', complexity: 2 },
                    'J': { strokes: 1, symmetry: 'none', complexity: 1 },
                    'K': { strokes: 3, symmetry: 'none', complexity: 3 },
                    'L': { strokes: 2, symmetry: 'none', complexity: 1 },
                    'M': { strokes: 4, symmetry: 'vertical', complexity: 3 },
                    'N': { strokes: 3, symmetry: 'none', complexity: 2 },
                    'P': { strokes: 2, symmetry: 'none', complexity: 2 },
                    'Q': { strokes: 2, symmetry: 'none', complexity: 3 },
                    'R': { strokes: 3, symmetry: 'none', complexity: 3 },
                    'S': { strokes: 1, symmetry: 'horizontal', complexity: 2 },
                    'T': { strokes: 2, symmetry: 'vertical', complexity: 1 },
                    'U': { strokes: 2, symmetry: 'vertical', complexity: 1 },
                    'V': { strokes: 2, symmetry: 'vertical', complexity: 1 },
                    'W': { strokes: 4, symmetry: 'vertical', complexity: 3 },
                    'X': { strokes: 2, symmetry: 'both', complexity: 2 },
                    'Y': { strokes: 3, symmetry: 'vertical', complexity: 2 },
                    'Z': { strokes: 3, symmetry: 'none', complexity: 2 },
                    '2': { strokes: 2, symmetry: 'none', complexity: 2 },
                    '3': { strokes: 2, symmetry: 'none', complexity: 2 },
                    '4': { strokes: 3, symmetry: 'none', complexity: 2 },
                    '5': { strokes: 3, symmetry: 'none', complexity: 2 },
                    '6': { strokes: 2, symmetry: 'none', complexity: 2 },
                    '7': { strokes: 2, symmetry: 'none', complexity: 1 },
                    '8': { strokes: 2, symmetry: 'both', complexity: 2 },
                    '9': { strokes: 2, symmetry: 'none', complexity: 2 }
                };
                
                // 易混淆字符组
                this.confusableGroups = [
                    ['A', 'H'], ['B', '8'], ['C', 'G'], ['D', 'O'],
                    ['E', 'F'], ['M', 'W'], ['N', 'M'], ['Q', 'O'],
                    ['S', '5'], ['V', 'U'], ['X', 'Y'], ['2', 'Z'],
                    ['6', '9'], ['3', '8']
                ];
            }
            
            // 识别字符，返回识别结果和置信度
            recognize(character, accuracy) {
                // 根据精度设置成功率
                let successRate;
                switch(accuracy) {
                    case 'high': successRate = 0.9; break;
                    case 'medium': successRate = 0.7; break;
                    case 'low': successRate = 0.5; break;
                }
                
                // 决定是否识别成功
                if (Math.random() < successRate) {
                    // 有小概率返回相似字符而非完全正确的字符
                    if (Math.random() < 0.1) {
                        // 找到相似字符
                        for (let group of this.confusableGroups) {
                            if (group.includes(character)) {
                                const similarChars = group.filter(c => c !== character);
                                return { result: similarChars[Math.floor(Math.random() * similarChars.length)], confidence: 0.7 + Math.random() * 0.2 };
                            }
                        }
                    }
                    // 识别正确
                    return { result: character, confidence: 0.8 + Math.random() * 0.2 };
                } else {
                    // 识别失败，返回随机字符
                    const allChars = Object.keys(this.characterFeatures);
                    let wrongChar;
                    do {
                        wrongChar = allChars[Math.floor(Math.random() * allChars.length)];
                    } while (wrongChar === character);
                    return { result: wrongChar, confidence: 0.3 + Math.random() * 0.4 };
                }
            }
            
            // 识别整个验证码字符串
            recognizeCaptcha(captcha, accuracy) {
                let result = '';
                let confidence = 1;
                
                for (let char of captcha) {
                    const recognition = this.recognize(char, accuracy);
                    result += recognition.result;
                    confidence *= recognition.confidence; // 整体置信度是各字符置信度的乘积
                }
                
                return {
                    result: result,
                    confidence: confidence,
                    isCorrect: result === captcha
                };
            }
        }
        
        // 滑块分析模拟器
        class SliderAnalyzer {
            constructor() {
                // 分析参数
                this.analysisParams = {
                    edgeDetection: 0.8,
                    patternMatching: 0.75,
                    positionEstimation: 0.9
                };
            }
            
            // 分析滑块目标位置
            analyzeTargetPosition(targetX, accuracy) {
                // 根据精度设置分析成功率
                let accuracyFactor;
                switch(accuracy) {
                    case 'high': accuracyFactor = 0.1; break; // 10% 误差范围
                    case 'medium': accuracyFactor = 0.2; break; // 20% 误差范围
                    case 'low': accuracyFactor = 0.4; break; // 40% 误差范围
                }
                
                // 计算可能的误差范围
                const maxDeviation = 30 * accuracyFactor; // 最大偏差像素
                
                // 生成带偏差的估计位置
                const estimatedX = targetX + (Math.random() * maxDeviation * 2 - maxDeviation);
                
                // 计算置信度
                const deviation = Math.abs(estimatedX - targetX);
                const confidence = Math.max(0, 1 - (deviation / (maxDeviation * 2)));
                
                // 判断是否在可接受范围内
                const isAcceptable = deviation <= 10; // 10像素内视为成功
                
                return {
                    estimatedX: estimatedX,
                    confidence: confidence,
                    isAcceptable: isAcceptable
                };
            }
            
            // 模拟人类拖动行为 - 增强版，增加更多随机抖动和非线性路径
            simulateHumanDrag(startX, targetX, trackWidth) {
                // 计算总距离
                const totalDistance = targetX - startX;
                
                // 人类拖动通常不是匀速的，会有加速和减速，且有自然抖动
                const dragPoints = [];
                const steps = Math.floor(Math.abs(totalDistance) / 3) + 20; // 更多步数，使路径更自然
                
                // 生成速度曲线 - 先加速后减速，增加更多变化
                const speedProfile = [];
                for (let i = 0; i < steps; i++) {
                    const t = i / (steps - 1);
                    // 使用更复杂的曲线模拟人类拖动速度变化
                    let speed = Math.sin(t * Math.PI) * 0.7 + 0.3; // 基础速度曲线
                    speed += (Math.random() * 0.2 - 0.1); // 添加随机波动
                    speedProfile.push(Math.max(0.2, Math.min(1.0, speed))); // 限制速度范围
                }
                
                // 计算每步位置，增加横向和纵向抖动
                let currentX = startX;
                const totalSpeed = speedProfile.reduce((sum, s) => sum + s, 0);
                const distancePerSpeedUnit = totalDistance / totalSpeed;
                
                // 添加一些随机的停顿点
                const pausePoints = new Set();
                const pauseCount = Math.floor(Math.random() * 3); // 0-2个停顿点
                for (let i = 0; i < pauseCount; i++) {
                    pausePoints.add(Math.floor(Math.random() * (steps - 5)) + 2);
                }
                
                for (let i = 0; i < steps; i++) {
                    // 处理停顿
                    if (pausePoints.has(i)) {
                        const pauseLength = Math.floor(Math.random() * 3) + 1;
                        for (let j = 0; j < pauseLength; j++) {
                            dragPoints.push(currentX);
                        }
                        continue;
                    }
                    
                    // 基础移动
                    currentX += speedProfile[i] * distancePerSpeedUnit;
                    
                    // 添加横向随机抖动，模拟人手不稳
                    const 抖动幅度 = 1.5 + Math.random() * 2; // 1.5-3.5像素的抖动
                    currentX += (Math.random() * 抖动幅度 * 2 - 抖动幅度);
                    
                    // 偶尔回退一点，增加非线性特征
                    if (Math.random() < 0.05) {
                        currentX -= speedProfile[i] * distancePerSpeedUnit * 0.5;
                    }
                    
                    dragPoints.push(currentX);
                }
                
                // 最后几步逐渐接近目标
                for (let i = 0; i < 5; i++) {
                    const t = i / 4;
                    currentX = currentX * (1 - t) + targetX * t + (Math.random() * 2 - 1);
                    dragPoints.push(currentX);
                }
                
                return dragPoints;
            }
            
            // 分析拖动路径是否符合人类行为特征
            analyzeDragPath(points) {
                if (points.length < 5) return false; // 路径点太少，不符合人类行为
                
                // 计算总位移
                const startX = points[0];
                const endX = points[points.length - 1];
                const totalDistance = Math.abs(endX - startX);
                
                if (totalDistance < 10) return false; // 移动距离太短
                
                // 检测是否有足够的横向抖动
                let totalJitter = 0;
                for (let i = 1; i < points.length; i++) {
                    totalJitter += Math.abs(points[i] - points[i-1]);
                }
                
                // 抖动比例，至少应该有总距离的20%作为抖动
                const jitterRatio = totalJitter / totalDistance;
                if (jitterRatio < 0.2) return false;
                
                // 检测是否为近似直线
                let maxDeviation = 0;
                const lineSlope = (endX - startX) / (points.length - 1);
                
                for (let i = 0; i < points.length; i++) {
                    const expectedX = startX + lineSlope * i;
                    const deviation = Math.abs(points[i] - expectedX);
                    maxDeviation = Math.max(maxDeviation, deviation);
                }
                
                // 如果最大偏差小于总距离的5%，则视为近似直线
                if (maxDeviation < totalDistance * 0.05) return false;
                
                // 所有检测通过
                return true;
            }
        }
        
        // 验证码核心逻辑
        class CaptchaSystem {
            constructor() {
                this.captchaType = 'text'; // 默认字符验证
                this.currentCaptcha = '';
                this.mathResult = null; // 存储数学问题的答案
                this.sliderTargetX = 0; // 滑块验证的目标位置
                this.isDragging = false; // 滑块是否正在被拖动
                this.dragPath = []; // 存储滑块拖动路径
                
                // 获取Canvas元素
                this.captchaCanvas = document.getElementById('captchaCanvas');
                this.captchaCtx = this.captchaCanvas.getContext('2d');
                
                // 初始化识别器
                this.characterRecognizer = new CharacterRecognizer();
                this.sliderAnalyzer = new SliderAnalyzer();
                
                // 初始化
                this.generateCaptcha();
                this.bindEvents();
            }
            
            // 绑定事件
            bindEvents() {
                // 刷新验证码
                document.getElementById('refreshCaptcha').addEventListener('click', () => {
                    this.generateCaptcha();
                    this.clearInput();
                    this.clearResult();
                });
                
                // 验证按钮
                document.getElementById('verifyBtn').addEventListener('click', () => {
                    this.verifyInput();
                });
                
                // 输入框回车验证
                document.getElementById('userInput').addEventListener('keypress', (e) => {
                    if (e.key === 'Enter') {
                        this.verifyInput();
                    }
                });
                
                // 切换验证类型
                document.querySelectorAll('input[name="captchaType"]').forEach(radio => {
                    radio.addEventListener('change', (e) => {
                        this.captchaType = e.target.value;
                        this.switchCaptchaType();
                        this.generateCaptcha();
                        this.clearInput();
                        this.clearResult();
                    });
                });
                
                // 滑块验证相关事件
                this.bindSliderEvents();
                
                // 测试相关事件
                this.bindTestEvent();
            }
            
            // 切换验证码类型显示
            switchCaptchaType() {
                const textCaptchaContainer = document.getElementById('textCaptchaContainer');
                const sliderCaptchaContainer = document.getElementById('sliderCaptchaContainer');
                const textInputContainer = document.getElementById('textInputContainer');
                
                if (this.captchaType === 'slider') {
                    textCaptchaContainer.classList.add('hidden');
                    sliderCaptchaContainer.classList.remove('hidden');
                    textInputContainer.classList.add('hidden');
                } else {
                    textCaptchaContainer.classList.remove('hidden');
                    sliderCaptchaContainer.classList.add('hidden');
                    textInputContainer.classList.remove('hidden');
                }
            }
            
            // 绑定滑块验证事件
            bindSliderEvents() {
                const sliderButton = document.getElementById('sliderButton');
                const sliderProgress = document.getElementById('sliderProgress');
                const puzzlePiece = document.getElementById('puzzlePiece');
                const sliderContainer = document.querySelector('.slider-container');
                const refreshSlider = document.getElementById('refreshSlider');
                
                // 滑块鼠标/触摸事件
                sliderButton.addEventListener('mousedown', (e) => {
                    this.startDrag(e.clientX);
                });
                
                document.addEventListener('mousemove', (e) => {
                    if (this.isDragging) {
                        this.handleDrag(e.clientX);
                    }
                });
                
                document.addEventListener('mouseup', () => {
                    if (this.isDragging) {
                        this.endDrag();
                    }
                });
                
                // 触摸设备支持
                sliderButton.addEventListener('touchstart', (e) => {
                    this.startDrag(e.touches[0].clientX);
                });
                
                document.addEventListener('touchmove', (e) => {
                    if (this.isDragging) {
                        e.preventDefault(); // 防止页面滚动
                        this.handleDrag(e.touches[0].clientX);
                    }
                }, { passive: false });
                
                document.addEventListener('touchend', () => {
                    if (this.isDragging) {
                        this.endDrag();
                    }
                });
                
                // 刷新滑块
                refreshSlider.addEventListener('click', () => {
                    this.generateCaptcha();
                    this.clearResult();
                });
            }
            
            // 开始拖动滑块
            startDrag(clientX) {
                this.isDragging = true;
                this.startX = clientX;
                this.initialLeft = 0; // 滑块初始位置
                this.dragPath = [0]; // 重置拖动路径并记录起始点
                document.getElementById('sliderText').textContent = "松开完成验证";
            }
            
            // 处理拖动
            handleDrag(clientX) {
                const sliderTrack = document.querySelector('.slider-track');
                const trackRect = sliderTrack.getBoundingClientRect();
                const maxX = trackRect.width - 50; // 滑块最大移动距离
                
                // 计算滑块位置
                let deltaX = clientX - this.startX;
                let newLeft = this.initialLeft + deltaX;
                
                // 限制在轨道内
                newLeft = Math.max(0, Math.min(newLeft, maxX));
                
                // 更新滑块和进度条
                this.updateSliderPosition(newLeft);
                
                // 记录拖动路径
                this.dragPath.push(newLeft);
            }
            
            // 更新滑块位置
            updateSliderPosition(left) {
                const sliderButton = document.getElementById('sliderButton');
                const sliderProgress = document.getElementById('sliderProgress');
                const puzzlePiece = document.getElementById('puzzlePiece');
                
                sliderButton.style.left = `${left}px`;
                sliderProgress.style.width = `${left + 25}px`; // 25是滑块一半宽度
                
                // 移动拼图块，考虑到图像区域和滑块轨道的宽度可能不同
                const imageContainer = document.querySelector('.slider-container');
                const imageWidth = imageContainer.offsetWidth;
                const trackWidth = document.querySelector('.slider-track').offsetWidth;
                
                // 计算比例并移动拼图块
                const ratio = imageWidth / trackWidth;
                puzzlePiece.style.left = `${left * ratio}px`;
            }
            
            // 结束拖动，验证结果 - 修复了无响应问题
            endDrag() {
                this.isDragging = false;
                document.getElementById('sliderText').textContent = "向右拖动滑块完成拼图";
                
                const sliderButton = document.getElementById('sliderButton');
                const currentLeft = parseFloat(sliderButton.style.left) || 0;
                const sliderTrack = document.querySelector('.slider-track');
                const trackWidth = sliderTrack.offsetWidth;
                const imageWidth = document.querySelector('.slider-container').offsetWidth;
                const ratio = imageWidth / trackWidth;
                
                // 计算当前拼图块位置
                const currentPieceX = currentLeft * ratio;
                
                // 验证拼图位置是否正确（放宽了验证条件，提高用户体验）
                const positionCorrect = Math.abs(currentPieceX - this.sliderTargetX) <= 15;
                
                // 验证拖动路径是否符合人类行为（有抖动，非直线）
                const pathValid = this.sliderAnalyzer.analyzeDragPath(this.dragPath);
                
                const resultElement = document.getElementById('verificationResult');
                if (positionCorrect && pathValid) {
                    this.showResult(resultElement, '验证成功！', 'bg-green-50 text-green-700 border border-green-200');
                    // 添加成功动画
                    document.getElementById('sliderButton').innerHTML = '<i class="fa fa-check text-secondary text-xl"></i>';
                } else if (!positionCorrect) {
                    this.showResult(resultElement, '验证失败，拼图未对齐', 'bg-red-50 text-red-700 border border-red-200');
                    // 失败时复位
                    setTimeout(() => {
                        this.updateSliderPosition(0);
                        document.getElementById('sliderButton').innerHTML = '<i class="fa fa-angle-right text-primary text-xl"></i>';
                    }, 500);
                } else {
                    this.showResult(resultElement, '验证失败，拖动行为不自然', 'bg-red-50 text-red-700 border border-red-200');
                    // 失败时复位
                    setTimeout(() => {
                        this.updateSliderPosition(0);
                        document.getElementById('sliderButton').innerHTML = '<i class="fa fa-angle-right text-primary text-xl"></i>';
                    }, 500);
                }
                
                // 确保结果显示
                resultElement.scrollIntoView({ behavior: 'smooth', block: 'nearest' });
            }
            
            // 生成验证码
            generateCaptcha() {
                if (this.captchaType === 'text') {
                    this.generateTextCaptcha();
                } else if (this.captchaType === 'math') {
                    this.generateMathCaptcha();
                } else if (this.captchaType === 'slider') {
                    this.generateSliderCaptcha();
                }
            }
            
            // 生成字符验证码（使用Canvas绘制图片形式）
            generateTextCaptcha() {
                // 清除Canvas
                this.captchaCtx.clearRect(0, 0, this.captchaCanvas.width, this.captchaCanvas.height);
                
                // 生成随机字符验证码 (4位字母数字组合)
                const chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789'; // 排除易混淆的字符
                let captcha = '';
                for (let i = 0; i < 4; i++) {
                    captcha += chars.charAt(Math.floor(Math.random() * chars.length));
                }
                this.currentCaptcha = captcha;
                this.mathResult = null;
                
                // 设置Canvas背景
                this.captchaCtx.fillStyle = '#f9f9f9';
                this.captchaCtx.fillRect(0, 0, this.captchaCanvas.width, this.captchaCanvas.height);
                
                // 绘制字符
                const charWidth = this.captchaCanvas.width / (captcha.length + 1);
                const charHeight = this.captchaCanvas.height * 0.6;
                const baseY = this.captchaCanvas.height / 2 + charHeight / 4;
                
                // 存储每个字符的位置信息，用于绘制接触字符的线条
                const charPositions = [];
                
                for (let i = 0; i < captcha.length; i++) {
                    // 随机字体大小
                    const fontSize = 30 + Math.random() * 10;
                    this.captchaCtx.font = `${fontSize}px Arial, sans-serif`;
                    this.captchaCtx.textBaseline = 'middle';
                    
                    // 随机字符颜色
                    const hue = Math.floor(Math.random() * 360);
                    this.captchaCtx.fillStyle = `hsl(${hue}, 70%, 40%)`;
                    
                    // 随机旋转角度 (-15到15度)
                    const rotation = (Math.random() * 30 - 15) * Math.PI / 180;
                    
                    // 字符位置
                    const x = charWidth * (i + 0.7);
                    const y = baseY + (Math.random() * 20 - 10); // 垂直方向随机偏移
                    
                    // 保存当前状态
                    this.captchaCtx.save();
                    
                    // 旋转字符
                    this.captchaCtx.translate(x, y);
                    this.captchaCtx.rotate(rotation);
                    
                    // 绘制字符
                    this.captchaCtx.fillText(captcha[i], 0, 0);
                    
                    // 恢复状态
                    this.captchaCtx.restore();
                    
                    // 记录字符位置和范围
                    charPositions.push({
                        char: captcha[i],
                        x: x,
                        y: y,
                        width: fontSize * 0.7, // 近似字符宽度
                        height: fontSize,
                        rotation: rotation
                    });
                }
                
                // 绘制多色干扰线，确保接触字符且只在字符区域内
                const lineCount = 3 + Math.floor(Math.random() * 3); // 3-5条线
                for (let i = 0; i < lineCount; i++) {
                    // 随机选择两个字符作为线条的起点和终点附近
                    const startCharIdx = Math.floor(Math.random() * charPositions.length);
                    let endCharIdx;
                    do {
                        endCharIdx = Math.floor(Math.random() * charPositions.length);
                    } while (endCharIdx === startCharIdx);
                    
                    const startChar = charPositions[startCharIdx];
                    const endChar = charPositions[endCharIdx];
                    
                    // 在字符范围内选择起点和终点
                    const startX = startChar.x + (Math.random() * startChar.width - startChar.width / 2);
                    const startY = startChar.y + (Math.random() * startChar.height - startChar.height / 2);
                    const endX = endChar.x + (Math.random() * endChar.width - endChar.width / 2);
                    const endY = endChar.y + (Math.random() * endChar.height - endChar.height / 2);
                    
                    // 创建贝塞尔曲线控制点，使线条更自然
                    const controlX1 = startX + (Math.random() * 40 - 20);
                    const controlY1 = startY + (Math.random() * 40 - 20);
                    const controlX2 = endX + (Math.random() * 40 - 20);
                    const controlY2 = endY + (Math.random() * 40 - 20);
                    
                    // 随机线条颜色
                    const hue = Math.floor(Math.random() * 360);
                    this.captchaCtx.strokeStyle = `hsl(${hue}, 60%, 50%)`;
                    this.captchaCtx.lineWidth = 1.5 + Math.random() * 1.5;
                    
                    // 绘制曲线
                    this.captchaCtx.beginPath();
                    this.captchaCtx.moveTo(startX, startY);
                    this.captchaCtx.bezierCurveTo(controlX1, controlY1, controlX2, controlY2, endX, endY);
                    this.captchaCtx.stroke();
                }
            }
            
            // 生成数学问题验证码 - 改进了干扰线
            generateMathCaptcha() {
                // 清除Canvas
                this.captchaCtx.clearRect(0, 0, this.captchaCanvas.width, this.captchaCanvas.height);
                
                // 生成随机数学问题
                const num1 = Math.floor(Math.random() * 10) + 1;
                const num2 = Math.floor(Math.random() * 10) + 1;
                const operators = ['+', '-', '*'];
                const operator = operators[Math.floor(Math.random() * 3)];
                
                // 确保减法结果不为负数
                let mathExpr, result;
                if (operator === '-') {
                    mathExpr = `${Math.max(num1, num2)} - ${Math.min(num1, num2)} = ?`;
                    result = Math.max(num1, num2) - Math.min(num1, num2);
                } else if (operator === '+') {
                    mathExpr = `${num1} + ${num2} = ?`;
                    result = num1 + num2;
                } else { // *
                    // 乘法使用较小的数字
                    const num1 = Math.floor(Math.random() * 5) + 1;
                    const num2 = Math.floor(Math.random() * 5) + 1;
                    mathExpr = `${num1} × ${num2} = ?`;
                    result = num1 * num2;
                }
                
                this.currentCaptcha = mathExpr;
                this.mathResult = result.toString();
                
                // 设置Canvas背景
                this.captchaCtx.fillStyle = '#f9f9f9';
                this.captchaCtx.fillRect(0, 0, this.captchaCanvas.width, this.captchaCanvas.height);
                
                // 添加网格背景效果
                this.captchaCtx.strokeStyle = 'rgba(0, 0, 0, 0.05)';
                this.captchaCtx.lineWidth = 1;
                const gridSize = 15;
                for (let x = 0; x < this.captchaCanvas.width; x += gridSize) {
                    this.captchaCtx.beginPath();
                    this.captchaCtx.moveTo(x, 0);
                    this.captchaCtx.lineTo(x, this.captchaCanvas.height);
                    this.captchaCtx.stroke();
                }
                for (let y = 0; y < this.captchaCanvas.height; y += gridSize) {
                    this.captchaCtx.beginPath();
                    this.captchaCtx.moveTo(0, y);
                    this.captchaCtx.lineTo(this.captchaCanvas.width, y);
                    this.captchaCtx.stroke();
                }
                
                // 绘制数学表达式
                this.captchaCtx.font = '24px Arial, sans-serif';
                this.captchaCtx.textBaseline = 'middle';
                this.captchaCtx.textAlign = 'center';
                this.captchaCtx.fillStyle = '#333';
                this.captchaCtx.fillText(mathExpr, this.captchaCanvas.width / 2, this.captchaCanvas.height / 2);
                
                // 改进的干扰线 - 更多样化的曲线和形状
                const lineCount = 3 + Math.floor(Math.random() * 2);
                for (let i = 0; i < lineCount; i++) {
                    // 随机线条颜色，增加透明度变化
                    const hue = Math.floor(Math.random() * 360);
                    const alpha = 0.3 + Math.random() * 0.4; // 0.3-0.7的透明度
                    this.captchaCtx.strokeStyle = `hsla(${hue}, 60%, 50%, ${alpha})`;
                    this.captchaCtx.lineWidth = 1.5 + Math.random() * 1;
                    
                    // 绘制更复杂的曲线
                    const startX = Math.random() * this.captchaCanvas.width * 0.3;
                    const startY = Math.random() * this.captchaCanvas.height;
                    const endX = this.captchaCanvas.width * 0.7 + Math.random() * this.captchaCanvas.width * 0.3;
                    const endY = Math.random() * this.captchaCanvas.height;
                    
                    // 随机控制点
                    const controlX1 = startX + (Math.random() * 60 - 30);
                    const controlY1 = startY + (Math.random() * 60 - 30);
                    const controlX2 = endX + (Math.random() * 60 - 30);
                    const controlY2 = endY + (Math.random() * 60 - 30);
                    
                    this.captchaCtx.beginPath();
                    this.captchaCtx.moveTo(startX, startY);
                    this.captchaCtx.bezierCurveTo(controlX1, controlY1, controlX2, controlY2, endX, endY);
                    this.captchaCtx.stroke();
                }
                
                // 添加随机点干扰
                const dotCount = 30 + Math.floor(Math.random() * 20);
                for (let i = 0; i < dotCount; i++) {
                    const x = Math.random() * this.captchaCanvas.width;
                    const y = Math.random() * this.captchaCanvas.height;
                    const radius = 0.5 + Math.random() * 1.5;
                    
                    const hue = Math.floor(Math.random() * 360);
                    const alpha = 0.2 + Math.random() * 0.5;
                    this.captchaCtx.fillStyle = `hsla(${hue}, 60%, 50%, ${alpha})`;
                    
                    this.captchaCtx.beginPath();
                    this.captchaCtx.arc(x, y, radius, 0, Math.PI * 2);
                    this.captchaCtx.fill();
                }
            }
            
            // 生成滑块验证码 - 优化图片显示
            generateSliderCaptcha() {
                // 随机选择背景图片，确保图片格式正确
                const images = [
                    'https://picsum.photos/id/1015/800/450',
                    'https://picsum.photos/id/1016/800/450',
                    'https://picsum.photos/id/1018/800/450',
                    'https://picsum.photos/id/1019/800/450',
                    'https://picsum.photos/id/1039/800/450'
                ];
                const randomImage = images[Math.floor(Math.random() * images.length)];
                
                // 设置背景图片，添加加载错误处理
                const puzzleImage = document.getElementById('puzzleImage');
                puzzleImage.style.backgroundImage = `url(${randomImage})`;
                puzzleImage.style.backgroundSize = 'cover';
                puzzleImage.style.backgroundPosition = 'center';
                
                // 预加载图片以确保正确显示
                const img = new Image();
                img.src = randomImage;
                img.onload = () => {
                    // 图片加载完成后更新显示
                    puzzleImage.style.backgroundImage = `url(${randomImage})`;
                    this.updatePuzzlePieceImage(randomImage);
                };
                img.onerror = () => {
                    // 图片加载失败时使用备用图片
                    const fallbackImage = 'https://picsum.photos/id/1025/800/450';
                    puzzleImage.style.backgroundImage = `url(${fallbackImage})`;
                    this.updatePuzzlePieceImage(fallbackImage);
                };
                
                // 随机生成拼图缺失位置
                const containerWidth = document.querySelector('.slider-container').offsetWidth;
                const maxX = containerWidth - 60; // 60是拼图块宽度
                const maxY = 180 - 60; // 180是容器高度，60是拼图块高度
                
                const targetX = 50 + Math.random() * (maxX - 50); // 避免太靠近左边
                const targetY = 20 + Math.random() * (maxY - 20); // 避免太靠近边缘
                
                // 记录目标位置
                this.sliderTargetX = targetX;
                
                // 设置拼图缺失区域
                const puzzleMissing = document.getElementById('puzzleMissing');
                puzzleMissing.style.left = `${targetX}px`;
                puzzleMissing.style.top = `${targetY}px`;
                
                // 设置拼图块初始位置和背景位置
                const puzzlePiece = document.getElementById('puzzlePiece');
                puzzlePiece.style.left = '0px';
                puzzlePiece.style.top = `${targetY}px`;
                puzzlePiece.style.backgroundPosition = `0px -${targetY}px`;
                
                // 重置滑块
                this.updateSliderPosition(0);
                document.getElementById('sliderButton').innerHTML = '<i class="fa fa-angle-right text-primary text-xl"></i>';
            }
            
            // 更新拼图块图片（用于图片加载完成后）
            updatePuzzlePieceImage(imageUrl) {
                const puzzlePiece = document.getElementById('puzzlePiece');
                puzzlePiece.style.backgroundImage = `url(${imageUrl})`;
                puzzlePiece.style.backgroundSize = 'cover';
            }
            
            // 验证用户输入
            verifyInput() {
                const userInput = document.getElementById('userInput').value.trim();
                const resultElement = document.getElementById('verificationResult');
                
                if (!userInput) {
                    this.showResult(resultElement, '请输入验证码', 'bg-yellow-50 text-yellow-700 border border-yellow-200');
                    return;
                }
                
                let isCorrect;
                if (this.captchaType === 'math') {
                    isCorrect = userInput === this.mathResult;
                } else {
                    isCorrect = userInput.toUpperCase() === this.currentCaptcha;
                }
                
                if (isCorrect) {
                    this.showResult(resultElement, '验证成功！', 'bg-green-50 text-green-700 border border-green-200');
                } else {
                    this.showResult(resultElement, '验证失败，请重试', 'bg-red-50 text-red-700 border border-red-200');
                }
            }
            
            // 显示验证结果
            showResult(element, text, className) {
                element.textContent = text;
                element.className = `p-3 rounded-lg mb-4 border ${className} animate-fadeIn`;
                element.classList.remove('hidden');
                
                // 添加淡入动画
                element.style.opacity = '0';
                element.style.transition = 'opacity 0.3s ease';
                setTimeout(() => {
                    element.style.opacity = '1';
                }, 10);
                
                // 字符验证成功后一段时间刷新验证码
                if (text === '验证成功！' && this.captchaType !== 'slider') {
                    setTimeout(() => {
                        this.generateCaptcha();
                        this.clearInput();
                        this.clearResult();
                    }, 2000);
                }
            }
            
            // 清除输入
            clearInput() {
                document.getElementById('userInput').value = '';
            }
            
            // 清除结果
            clearResult() {
                const resultElement = document.getElementById('verificationResult');
                resultElement.classList.add('hidden');
                resultElement.textContent = '';
                resultElement.className = 'hidden p-3 rounded-lg mb-4 border';
            }
            
            // 绑定测试事件
            bindTestEvent() {
                document.getElementById('startTestBtn').addEventListener('click', async () => {
                    this.runTests();
                });
            }
            
            // 运行测试
            async runTests() {
                const testCount = parseInt(document.getElementById('testCount').value) || 5;
                const accuracy = document.querySelector('input[name="recognitionAccuracy"]:checked').value;
                const testResultsElement = document.getElementById('testResults');
                const totalTestsElement = document.getElementById('totalTests');
                const successfulTestsElement = document.getElementById('successfulTests');
                const failedTestsElement = document.getElementById('failedTests');
                
                // 重置测试结果
                testResultsElement.innerHTML = '';
                document.getElementById('testStats').classList.remove('hidden');
                
                let total = 0;
                let success = 0;
                let failed = 0;
                
                // 根据当前选中的验证类型进行测试
                const currentType = document.querySelector('input[name="captchaType"]:checked').value;
                
                for (let i = 0; i < testCount; i++) {
                    total++;
                    totalTestsElement.textContent = total;
                    
                    // 刷新验证码
                    this.generateCaptcha();
                    
                    // 等待验证码生成
                    await new Promise(resolve => setTimeout(resolve, 300));
                    
                    let result, testText;
                    
                    if (currentType === 'slider') {
                        // 滑块验证测试
                        testResultsElement.innerHTML += `<div class="test-result">测试 ${i+1}: 分析滑块位置...</div>`;
                        
                        // 分析目标位置
                        const trackWidth = document.querySelector('.slider-track').offsetWidth;
                        const imageWidth = document.querySelector('.slider-container').offsetWidth;
                        const ratio = trackWidth / imageWidth;
                        const targetXInTrack = this.sliderTargetX * ratio;
                        
                        const analysis = this.sliderAnalyzer.analyzeTargetPosition(targetXInTrack, accuracy);
                        
                        // 模拟拖动
                        await new Promise(resolve => setTimeout(resolve, 500));
                        
                        const dragPoints = this.sliderAnalyzer.simulateHumanDrag(0, analysis.estimatedX, trackWidth);
                        
                        // 执行模拟拖动
                        testResultsElement.innerHTML += `<div class="test-result">测试 ${i+1}: 模拟拖动...</div>`;
                        
                        for (let point of dragPoints) {
                            this.updateSliderPosition(point);
                            await new Promise(resolve => setTimeout(resolve, 10));
                        }
                        
                        // 检查结果
                        const finalPosition = dragPoints[dragPoints.length - 1];
                        const finalPieceX = finalPosition * (imageWidth / trackWidth);
                        const isSuccess = Math.abs(finalPieceX - this.sliderTargetX) <= 10;
                        
                        if (isSuccess) {
                            success++;
                            testText = `<div class="test-result text-green-700">测试 ${i+1}: 滑块验证成功 (置信度: ${analysis.confidence.toFixed(2)})</div>`;
                        } else {
                            failed++;
                            testText = `<div class="test-result text-red-700">测试 ${i+1}: 滑块验证失败 (置信度: ${analysis.confidence.toFixed(2)})</div>`;
                        }
                        
                        // 重置滑块
                        await new Promise(resolve => setTimeout(resolve, 500));
                        this.updateSliderPosition(0);
                        
                    } else {
                        // 字符或数学验证测试
                        testResultsElement.innerHTML += `<div class="test-result">测试 ${i+1}: 识别验证码...</div>`;
                        
                        // 识别验证码
                        await new Promise(resolve => setTimeout(resolve, 500));
                        
                        let recognition;
                        if (currentType === 'math') {
                            // 对于数学问题，简单模拟识别答案
                            const successRate = accuracy === 'high' ? 0.9 : (accuracy === 'medium' ? 0.7 : 0.5);
                            const isSuccess = Math.random() < successRate;
                            recognition = {
                                result: isSuccess ? this.mathResult : Math.floor(Math.random() * 100).toString(),
                                isCorrect: isSuccess,
                                confidence: isSuccess ? (0.8 + Math.random() * 0.2) : (0.3 + Math.random() * 0.4)
                            };
                        } else {
                            // 字符验证码识别
                            recognition = this.characterRecognizer.recognizeCaptcha(this.currentCaptcha, accuracy);
                        }
                        
                        if (recognition.isCorrect) {
                            success++;
                            testText = `<div class="test-result text-green-700">测试 ${i+1}: 识别成功 - 识别结果: "${recognition.result}", 实际值: "${this.currentCaptcha || this.mathResult}", 置信度: ${recognition.confidence.toFixed(2)}</div>`;
                        } else {
                            failed++;
                            testText = `<div class="test-result text-red-700">测试 ${i+1}: 识别失败 - 识别结果: "${recognition.result}", 实际值: "${this.currentCaptcha || this.mathResult}", 置信度: ${recognition.confidence.toFixed(2)}</div>`;
                        }
                    }
                    
                    // 更新结果显示
                    testResultsElement.innerHTML += testText;
                    testResultsElement.scrollTop = testResultsElement.scrollHeight;
                    successfulTestsElement.textContent = success;
                    failedTestsElement.textContent = failed;
                    
                    // 测试间隔
                    await new Promise(resolve => setTimeout(resolve, 800));
                }
                
                testResultsElement.innerHTML += `<div class="mt-2 font-medium">测试完成 - 成功率: ${Math.round((success / total) * 100)}%</div>`;
                testResultsElement.scrollTop = testResultsElement.scrollHeight;
            }
        }
        
        // 初始化验证码系统
        document.addEventListener('DOMContentLoaded', () => {
            new CaptchaSystem();
        });
    </script>
</body></html>
